/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.gov.cemaden.imagefilter.repository;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 *
 * @author Alan
 */
public class XMLRepositoryReader extends DefaultHandler implements RepositoryReader {
        
    Map<String, String> elements;
    List<String> input, output;
    String sInput, sOutput;
    Boolean bInput, bOutput;
    private Logger logger = Logger.getLogger(XMLRepositoryReader.class.getName());
    
    public XMLRepositoryReader( String filename ){
        
        elements = new HashMap<String, String>();
        input = new ArrayList<String>();
        output = new ArrayList<String>();
        sInput = new String();
        sOutput = new String();
        bInput = bOutput = false;
        
        parseDocument(filename);
    }        
    
    private void parseDocument( String filename ){
        
        SAXParserFactory factory = SAXParserFactory.newInstance();        
        try {            
            SAXParser parser = factory.newSAXParser();
            parser.parse(filename, this);                
            
        }
        catch( ParserConfigurationException e ){
            logger.fatal("There's something wrong with the XML datasource configuration - "
                    + "Message: " + e.getMessage() + " - Cause: " + e.getCause());
            e.printStackTrace();
        }
        catch( SAXException e ){
            logger.fatal("Error when parsing the XML file - Message: " 
                    + e.getMessage() + " - Cause: " + e.getCause());
            e.printStackTrace();
        }
        catch( Exception e ){
            logger.fatal("Something terribly wrong happened - Message: " 
                    + e.getMessage() + " - Cause: " + e.getCause());
            e.printStackTrace();
        }
    }
    
    @Override
    public Map<String, String> getElements(){                                
        
        if(elements.isEmpty()){
            logger.error("There's something wrong with your repository or it's empty.");
            throw new RuntimeException("There's something wrong with your repository or it's empty. "
                    + "You need to configure each filename node with input and output.");
        }
        return elements;
    }
    
    @Override
    public List<String> getInputElements(){
        for(Map.Entry<String, String> entry : elements.entrySet()){
            input.add(entry.getValue());
        }
        return input;
    }
    
    @Override
    public List<String> getOutputElements(){
        for(Map.Entry<String, String> entry : elements.entrySet()){
            output.add(entry.getKey());
        }
        return output;
    }
    
    @Override
    public void startElement( String uri, String localName, String qName, 
            Attributes attributes ) throws SAXException {
        
        if( qName.equalsIgnoreCase("input") ){
            bInput = true;
        }
        else if( qName.equalsIgnoreCase("output") ){
            bOutput = true;
        }        
    }
    
    @Override
    public void endElement(String uri, String localName, String qName)  
      throws SAXException {  
        if( qName.equalsIgnoreCase("filename") ){
            if( !sOutput.isEmpty() && !sInput.isEmpty() ){
                elements.put(sOutput, sInput);
            }
        }
    }
    
    @Override
    public void characters(char ch[], int start, int length)  
      throws SAXException {

        if( bInput ){            
            sInput = new String(ch, start, length);
            bInput = false;
        }
        else if( bOutput ){
            sOutput = new String(ch, start, length);
            bOutput = false;
        }
    }
    
}
